#include "VSBind.h"
#include "VSRenderer.h"
#include "VSResourceManager.h"
#include "VSGraphicInclude.h"
#include "VSStream.h"
using namespace VSEngine2;
VSArray<VSBind *> VSBind::ms_DynamicTwoBindArray;
VSArray<VSBind *> VSBind::ms_BindArray;
IMPLEMENT_RTTI_NoCreateFun(VSBind,VSObject)
IMPLEMENT_INITIAL_NO_CLASS_FACTORY_BEGIN(VSBind)
IMPLEMENT_INITIAL_NO_CLASS_FACTORY_END
BEGIN_ADD_PROPERTY(VSBind,VSObject)
REGISTER_PROPERTY(m_bIsStatic,IsStatic,VSProperty::F_SAVE_LOAD_CLONE);
REGISTER_PROPERTY(m_uiSwapChainNum,SwapChainNum,VSProperty::F_SAVE_LOAD_CLONE);
REGISTER_PROPERTY(m_uiLockFlag,LockFlag,VSProperty::F_SAVE_LOAD_CLONE);
REGISTER_PROPERTY(m_uiMemType,MemType,VSProperty::F_SAVE_LOAD_CLONE);
END_ADD_PROPERTY
VSResourceIdentifier* VSBind::GetIdentifier ()
{
	if (!m_InfoArray.GetNum())
	{
		return NULL;
	}
	VSResourceIdentifier * pID = NULL;
	pID = m_InfoArray[m_uiCurID].ID;
	return pID;
}
void VSBind::ExChange()
{
	if (!m_bIsStatic && m_uiSwapChainNum == 2)
	{
		m_uiCurID = (m_uiCurID + 1) % m_uiSwapChainNum;
	}	
}
unsigned int VSBind::GetInfoQuantity () const
{
	return m_InfoArray.GetNum();
}
VSBind::VSBind(unsigned int uiMemType)
{
	m_InfoArray.Clear();
	m_bIsStatic = 1;
	m_uiSwapChainNum = 1;
	m_uiCurID = 0;
	m_uiLockFlag = LF_NOOVERWRITE;
	m_pUser = NULL;
	m_uiMemType = uiMemType;
	ms_BindArray.AddElement(this);
}
VSBind::~VSBind()
{
	if (!m_bIsStatic && m_uiSwapChainNum == 2)
	{
		for (unsigned int i = 0 ;i  < ms_DynamicTwoBindArray.GetNum() ; i++)
		{
			if (ms_DynamicTwoBindArray[i] == this)
			{
				ms_DynamicTwoBindArray.Erase(i);
				break;
			}
		}
	}
	for (unsigned int i = 0 ;i  < ms_BindArray.GetNum() ; i++)
	{
		if (ms_BindArray[i] == this)
		{
			ms_BindArray.Erase(i);
			break;
		}
	}
	ReleaseResource();
}
void VSBind::Bind(VSResourceIdentifier* pID)
{
	if(!pID)
		return ;
	INFO_TYPE Info;
	Info.ID = pID;
	m_InfoArray.AddElement(Info);
}
unsigned int VSBind::DiskUse()const
{
	unsigned int Use = VSObject::DiskUse();
	Use += sizeof(bool);
	Use += sizeof(unsigned int);
	Use += sizeof(unsigned int);
	Use += sizeof(unsigned int);
	return Use;
}
bool VSBind::Save(VSStream & rStream,unsigned int &iSaveUse)const
{
	if(!VSObject::Save(rStream,iSaveUse))
		return 0;

	if(!rStream.Write(&m_bIsStatic,sizeof(bool)))
		return 0;
	iSaveUse += sizeof(bool);

	if(!rStream.Write(&m_uiSwapChainNum,sizeof(unsigned int)))
		return 0;
	iSaveUse += sizeof(unsigned int);

	if(!rStream.Write(&m_uiLockFlag,sizeof(unsigned int)))
		return 0;
	iSaveUse += sizeof(unsigned int);

	if(!rStream.Write(&m_uiMemType,sizeof(unsigned int)))
		return 0;
	iSaveUse += sizeof(unsigned int);
	return 1;
}
bool VSBind::Load(VSStream & rStream,unsigned int &iSaveUse)
{
	if(!VSObject::Load(rStream,iSaveUse))
		return 0;

	bool bIsStatic;
	unsigned int uiSwapChainNum;
	if(!rStream.Read(&bIsStatic,sizeof(bool)))
		return 0;
	iSaveUse += sizeof(bool);

	if(!rStream.Read(&uiSwapChainNum,sizeof(unsigned int)))
		return 0;
	iSaveUse += sizeof(unsigned int);

	SetStatic(bIsStatic,uiSwapChainNum);

	if(!rStream.Read(&m_uiLockFlag,sizeof(unsigned int)))
		return 0;
	iSaveUse += sizeof(unsigned int);

	if(!rStream.Read(&m_uiMemType,sizeof(unsigned int)))
		return 0;
	iSaveUse += sizeof(unsigned int);
	return 1;
}
bool VSBind::Clone(const VSObject *pObject,unsigned int uiType)
{
	const VSBind* Temp = DynamicCast<VSBind>(pObject); 
	if(!Temp)
		return 0;
	if(VSObject::Clone(pObject,uiType))
	{
		m_InfoArray.Clear();
		SetStatic(Temp->m_bIsStatic,Temp->m_uiSwapChainNum);
		m_uiMemType = Temp->m_uiMemType;
		return 1;
	}
	else
	{
		return 0;

	}

}
bool VSBind::LoadResource(VSRenderer * pRender)
{
	if(!pRender)
		return 0;
	if (m_uiMemType == MT_RAM)
	{
		return 1;
	}
	if(m_uiSwapChainNum == m_InfoArray.GetNum())
		return 1;
	else
	{
		m_pUser = pRender;
		for (unsigned int i = 0 ; i < m_uiSwapChainNum ; i++)
		{
			VSResourceIdentifier *pID = NULL;
			if(!OnLoadResource(pID))
				return 0;
			if(!pID)
				return 0;
			Bind(pID);
		}
		return 1;	
	
	}
	
}
bool VSBind::ReleaseResource()
{
	for (unsigned int i = 0 ; i < m_InfoArray.GetNum() ; i++)
	{
		INFO_TYPE &rInfo = m_InfoArray[i];
		if(!OnReleaseResource(rInfo.ID))
			return 0;
	}
	m_InfoArray.Clear();
	return 1;
}
void VSBind::SetStatic(bool bIsStatic,unsigned int uiSwapChainNum)
{
	m_bIsStatic = bIsStatic;
	
	if(!bIsStatic && !uiSwapChainNum)
		uiSwapChainNum = 1;
	if(m_bIsStatic)
	{
		m_uiSwapChainNum = 1;	
	}
	else
	{
		if (VSResourceManager::ms_bRenderThread)
		{
			if (uiSwapChainNum >= 2)
			{
				uiSwapChainNum = 2;
				ms_DynamicTwoBindArray.AddElement(this);
			}
		}
		else
		{
			uiSwapChainNum = 1;
		}
		m_uiSwapChainNum = uiSwapChainNum;
	}

	m_uiCurID = 0;

}
unsigned int VSBind::GetByteSize()const
{
	return 0;
}
